<?php
/**
 * 响应格式化工具
 *
 * @author Claude Code
 * @since 2025-11-03
 */

namespace app\common\helpers;

/**
 * 统一响应格式化工具类
 *
 * 用于标准化API响应格式
 */
class ResponseFormatter
{
    /**
     * 成功响应
     *
     * @param mixed $data 数据
     * @param string $message 消息
     * @param int $code 状态码
     * @param array $extra 额外信息
     * @return array
     */
    public static function success($data = null, string $message = '操作成功', int $code = 0, array $extra = []): array
    {
        $response = [
            'code' => $code,
            'msg' => $message,
            'time' => time(),
            'data' => $data
        ];

        if (!empty($extra)) {
            $response = array_merge($response, $extra);
        }

        return $response;
    }

    /**
     * 错误响应
     *
     * @param string $message 错误消息
     * @param int $code 错误码
     * @param mixed $data 数据
     * @param int $httpCode HTTP状态码
     * @return array
     */
    public static function error(string $message = '操作失败', int $code = 1, $data = null, int $httpCode = 400): array
    {
        return [
            'code' => $code,
            'msg' => $message,
            'time' => time(),
            'data' => $data,
            'http_code' => $httpCode
        ];
    }

    /**
     * 分页响应
     *
     * @param array $list 数据列表
     * @param int $total 总数
     * @param int $page 页码
     * @param int $limit 每页数量
     * @param array $extra 额外信息
     * @return array
     */
    public static function paginate(array $list, int $total, int $page, int $limit, array $extra = []): array
    {
        $response = [
            'list' => $list,
            'total' => $total,
            'page' => $page,
            'limit' => $limit,
            'pages' => ceil($total / $limit)
        ];

        return self::success($response, '获取成功', 0, $extra);
    }

    /**
     * 创建成功响应
     *
     * @param mixed $data 数据
     * @param string $message 消息
     * @return array
     */
    public static function created($data = null, string $message = '创建成功'): array
    {
        return self::success($data, $message, 0);
    }

    /**
     * 更新成功响应
     *
     * @param mixed $data 数据
     * @param string $message 消息
     * @return array
     */
    public static function updated($data = null, string $message = '更新成功'): array
    {
        return self::success($data, $message, 0);
    }

    /**
     * 删除成功响应
     *
     * @param string $message 消息
     * @return array
     */
    public static function deleted(string $message = '删除成功'): array
    {
        return self::success(null, $message, 0);
    }

    /**
     * 未授权响应
     *
     * @param string $message 消息
     * @return array
     */
    public static function unauthorized(string $message = '未授权访问'): array
    {
        return self::error($message, 401, null, 401);
    }

    /**
     * 禁止访问响应
     *
     * @param string $message 消息
     * @return array
     */
    public static function forbidden(string $message = '禁止访问'): array
    {
        return self::error($message, 403, null, 403);
    }

    /**
     * 资源不存在响应
     *
     * @param string $message 消息
     * @return array
     */
    public static function notFound(string $message = '资源不存在'): array
    {
        return self::error($message, 404, null, 404);
    }

    /**
     * 验证失败响应
     *
     * @param string|array $message 错误消息
     * @param array $errors 错误详情
     * @return array
     */
    public static function validationFailed($message = '验证失败', array $errors = []): array
    {
        $data = null;
        if (!empty($errors)) {
            $data = ['errors' => $errors];
        }

        return self::error($message, 422, $data, 422);
    }

    /**
     * 服务器错误响应
     *
     * @param string $message 消息
     * @param string $traceId 追踪ID
     * @return array
     */
    public static function serverError(string $message = '服务器内部错误', string $traceId = ''): array
    {
        $data = null;
        if ($traceId) {
            $data = ['trace_id' => $traceId];
        }

        return self::error($message, 500, $data, 500);
    }

    /**
     * 业务逻辑错误响应
     *
     * @param string $message 消息
     * @param int $code 错误码
     * @param mixed $data 数据
     * @return array
     */
    public static function businessError(string $message, int $code = 1001, $data = null): array
    {
        return self::error($message, $code, $data);
    }

    /**
     * 参数错误响应
     *
     * @param string $message 消息
     * @param array $errors 错误详情
     * @return array
     */
    public static function paramError(string $message = '参数错误', array $errors = []): array
    {
        return self::validationFailed($message, $errors);
    }

    /**
     * 数据库错误响应
     *
     * @param string $message 消息
     * @param string $sql SQL语句
     * @return array
     */
    public static function dbError(string $message = '数据库错误', string $sql = ''): array
    {
        $data = null;
        if ($sql && app()->isDebug()) {
            $data = ['sql' => $sql];
        }

        return self::error($message, 1002, $data);
    }

    /**
     * 缓存错误响应
     *
     * @param string $message 消息
     * @param string $key 缓存键
     * @return array
     */
    public static function cacheError(string $message = '缓存错误', string $key = ''): array
    {
        $data = null;
        if ($key && app()->isDebug()) {
            $data = ['cache_key' => $key];
        }

        return self::error($message, 1003, $data);
    }

    /**
     * 第三方服务错误响应
     *
     * @param string $message 消息
     * @param string $service 服务名称
     * @return array
     */
    public static function serviceError(string $message = '第三方服务错误', string $service = ''): array
    {
        $data = null;
        if ($service) {
            $data = ['service' => $service];
        }

        return self::error($message, 1004, $data);
    }

    /**
     * 权限不足响应
     *
     * @param string $message 消息
     * @param string $permission 权限
     * @return array
     */
    public static function insufficientPermission(string $message = '权限不足', string $permission = ''): array
    {
        $data = null;
        if ($permission) {
            $data = ['permission' => $permission];
        }

        return self::error($message, 1005, $data);
    }

    /**
     * 资源冲突响应
     *
     * @param string $message 消息
     * @param string $resource 资源类型
     * @param mixed $identifier 资源标识
     * @return array
     */
    public static function conflict(string $message = '资源冲突', string $resource = '', $identifier = null): array
    {
        $data = null;
        if ($resource) {
            $data = ['resource' => $resource];
            if ($identifier !== null) {
                $data['identifier'] = $identifier;
            }
        }

        return self::error($message, 409, $data, 409);
    }

    /**
     * 请求频率限制响应
     *
     * @param string $message 消息
     * @param int $retryAfter 重试间隔（秒）
     * @return array
     */
    public static function tooManyRequests(string $message = '请求过于频繁', int $retryAfter = 60): array
    {
        $response = self::error($message, 429, null, 429);
        $response['retry_after'] = $retryAfter;

        return $response;
    }

    /**
     * 自定义响应
     *
     * @param int $code 状态码
     * @param string $msg 消息
     * @param mixed $data 数据
     * @param int $httpCode HTTP状态码
     * @param array $extra 额外信息
     * @return array
     */
    public static function custom(int $code, string $msg, $data = null, int $httpCode = 200, array $extra = []): array
    {
        $response = [
            'code' => $code,
            'msg' => $msg,
            'time' => time(),
            'data' => $data
        ];

        if (!empty($extra)) {
            $response = array_merge($response, $extra);
        }

        return $response;
    }

    /**
     * API版本响应
     *
     * @param string $version 版本号
     * @param mixed $data 数据
     * @param string $message 消息
     * @return array
     */
    public static function version(string $version, $data = null, string $message = 'success'): array
    {
        return self::success($data, $message, 0, ['version' => $version]);
    }

    /**
     * 分页元数据响应
     *
     * @param int $total 总数
     * @param int $page 页码
     * @param int $limit 每页数量
     * @param int $totalPages 总页数
     * @param array $extra 额外信息
     * @return array
     */
    public static function paginationMeta(int $total, int $page, int $limit, int $totalPages, array $extra = []): array
    {
        return [
            'total' => $total,
            'page' => $page,
            'limit' => $limit,
            'total_pages' => $totalPages,
            'has_next' => $page < $totalPages,
            'has_prev' => $page > 1
        ];
    }

    /**
     * 集合响应（无分页）
     *
     * @param array $data 数据
     * @param int $count 数量
     * @param string $message 消息
     * @return array
     */
    public static function collection(array $data, int $count = 0, string $message = '获取成功'): array
    {
        if ($count === 0) {
            $count = count($data);
        }

        return self::success([
            'data' => $data,
            'count' => $count
        ], $message);
    }

    /**
     * 单资源响应
     *
     * @param array|object $data 数据
     * @param string $message 消息
     * @return array
     */
    public function resource($data, string $message = '获取成功'): array
    {
        return self::success($data, $message);
    }

    /**
     * 操作结果响应
     *
     * @param bool $success 是否成功
     * @param string $message 消息
     * @param mixed $data 数据
     * @return array
     */
    public static function result(bool $success, string $message = '', $data = null): array
    {
        if ($success) {
            return self::success($data, $message ?: '操作成功');
        } else {
            return self::error($message ?: '操作失败');
        }
    }
}
